import axios from 'axios'
import type { AxiosInstance } from 'axios'
// 拦截器 ：请求拦截器 token
import type { hyRequestConfig } from './type'

// 定义一个请求的类
class HYRequest {
  // 每次 new   request实例-》 对应不同的axios的实例
  instance: AxiosInstance
  constructor(config: hyRequestConfig) {
    // create创建axios实例 config 对应实例的参数
    this.instance = axios.create(config)
    // 每个instance实例都添加拦截器 全局
    this.instance.interceptors.request.use(
      (config) => {
        console.log('全局请求成功的拦截')

        return config
      },
      (err) => {
        console.log('全局请求失败的拦截')

        return err
      }
    )
    this.instance.interceptors.response.use(
      (res) => {
        console.log('全局响应成功的拦截')

        return res.data
      },
      (err) => {
        console.log('全局响应失败的拦截')

        return err
      }
    )
    // 针对特定的hyrequest实例添加拦截器  new实例的时候 拦截器
    // if (config.interceptors) {//类型缩小
    //     this.instance.interceptors.request.use(
    //       config.interceptors.requestSuccessFn,
    //       config.interceptors.requestFailureFn
    //     )
    //     this.instance.interceptors.response.use(
    //         config.interceptors.responseSuccessFn,
    //         config.interceptors.responseFailureFn
    //         )
    // }
    this.instance.interceptors.request.use(
      config.interceptors?.requestSuccessFn,
      config.interceptors?.requestFailureFn
    )
    this.instance.interceptors.response.use(
      config.interceptors?.responseSuccessFn,
      config.interceptors?.responseFailureFn
    )
  }
  // 封装网络请求的方法
  request<T = any>(config: hyRequestConfig<T>) {
    // 调用请求方法的时候 具体的请求传入的拦截器
    // 单次请求 有传入拦截器 自己回调一次 拦截器
    // 请求拦截器
    if (config.interceptors?.requestSuccessFn) {
      // 有改config 自己重新赋值config
      config = config.interceptors.requestSuccessFn(config)
    }
    // new Promise没类型 new Promise<any>
    return new Promise<T>((resolve, reject) => {
      // 自己手动new了一个Promise 发送请求 拿到响应成功时 判断是否传入拦截器。
      this.instance
        .request<any, T>(config)
        .then((res) => {
          // 如果传入响应成功的拦截器  自己回调一次 拦截器
          if (config.interceptors?.responseSuccessFn) {
            res = config.interceptors?.responseSuccessFn(res)
          }
          resolve(res)
        })
        .catch((err) => {
          reject(err)
        })
    })
  }
  // 具体请求调用上面封装的request
  get<T = any>(config: hyRequestConfig<T>) {
    return this.request({ ...config, method: 'GET' })
  }
  post<T = any>(config: hyRequestConfig<T>) {
    return this.request({ ...config, method: 'POST' })
  }
  delete<T = any>(config: hyRequestConfig<T>) {
    return this.request({ ...config, method: 'DELETE' })
  }
  patch<T = any>(config: hyRequestConfig<T>) {
    return this.request({ ...config, method: 'PATCH' })
  }
}
export default HYRequest
